﻿using System;
using System.Collections.Generic;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;
using System.Xml;
using Excel = Microsoft.Office.Interop.Excel;
using System.IO;
using System.Threading;
using Constants;
using System.Net;


namespace Budget
{
    public partial class FormExpense : Form
    {
        BindingList<string> m_bindingList;
        DataTable m_ExpenseDataTable;
        BudgetFunctions m_BudgetFunctions;

        public FormExpense(ref DataSet i_ExpenseDataSet)
        {
            InitializeComponent();

            m_BudgetFunctions = new BudgetFunctions();
            GetComboboxValues();
            this.m_ExpenseDataTable = i_ExpenseDataSet.Tables[Tables.Expenses];
            m_BudgetFunctions.AutoCompleteText(ref this.textBoxDescription, m_ExpenseDataTable.DefaultView.ToTable(true, Fields.Description), Fields.Description);
        }

        private void GetComboboxValues()
        {
            m_BudgetFunctions.UpdateComboboxValues(ref m_bindingList, "ExpenseCategory", ref this.comboBoxCategory, "Others");
            this.comboBoxCurrency.SelectedIndex = this.comboBoxCurrency.Items.IndexOf("₪");
        }

        private void buttonQuit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void AddNewCatagoryToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            string value = null;

            if (InputBox.Show("New Category", "Enter New Category", ref value) == DialogResult.OK)
            {
                m_bindingList.Add(value);
            }
        }

        private void FormExpense_FormClosed(object sender, FormClosedEventArgs e)
        {
            this.m_BudgetFunctions.SaveComboBoxToXmlFile(m_bindingList, "ExpenseCategory");
        }

        private void RemoveCategoryToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormRemoveCategory formRemoveCategory = new FormRemoveCategory(m_bindingList);
            if(formRemoveCategory.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                DialogResult result = MessageBox.Show("Are you sure you want to remove " + m_bindingList.ElementAt(formRemoveCategory.RemoveAtIndex()) + " Category?","Remove Category",MessageBoxButtons.YesNo,MessageBoxIcon.Question);

                if (result == System.Windows.Forms.DialogResult.Yes)
                {
                    m_bindingList.RemoveAt(formRemoveCategory.RemoveAtIndex());
                }

            }
        }

        private void buttonAdd_Click(object sender, EventArgs e)
        {
            try
            {
                List<DataRow> newExpenseRow;
                this.BuildExpenseRow(out newExpenseRow);

                foreach (DataRow datarow in newExpenseRow)
                {
                    m_ExpenseDataTable.Rows.Add(datarow);
                }

                MessageBox.Show("New expense added succesfully");

                this.ClearFormValues();
            }

            catch(FormatException)
            {
                MessageBox.Show("Wrong data in amount field: " + textBoxAmount.Text);
                textBoxAmount.Clear();
            }

            catch(ArgumentNullException i_nullException)
            {
                MessageBox.Show(i_nullException.Message);
                if (i_nullException.Equals("textBoxDescription"))
                {
                    textBoxDescription.Clear();
                }
            }

            catch (Exception ex)
            {
                MessageBox.Show("Exception Occured while releasing object " + ex.ToString());
            }
        }

        private void ClearFormValues()
        {
            textBoxAmount.Clear();
            textBoxDescription.Clear();
            this.comboBoxCategory.SelectedIndex = this.comboBoxCategory.Items.IndexOf("Others");
            checkBoxShared.Checked = false;
        }

        private void BuildExpenseRow(out List<DataRow> i_newExpenseRow)
        {
            i_newExpenseRow = new List<DataRow>();
            i_newExpenseRow.Add(m_ExpenseDataTable.NewRow());
            
            i_newExpenseRow[0][Fields.Date] = (dateTimePicker1.Value.Date.ToShortDateString());

            i_newExpenseRow[0][Fields.Description] = ValidateDescriptionData();

            ValidateUserData();

            i_newExpenseRow[0][Fields.Category] =  comboBoxCategory.Text;
            i_newExpenseRow[0][Fields.Shared] = (checkBoxShared.Checked && checkBoxShared.Enabled) ? 1 : 0;

            if (radioButtonSplit.Checked == false)
            {
                i_newExpenseRow[0][Fields.User] = radioButtonOfri.Checked ? Users.Ofri : Users.Refael;
                i_newExpenseRow[0][Fields.Amount] = GetAmountWithExchRate(double.Parse(textBoxAmount.Text),i_newExpenseRow[0][Fields.Date].ToString(),GetOriginalCurrency(),"ils");
            }
            else
            {
                this.BuildSplitExpenseRow(ref i_newExpenseRow);
            }
        }

        private void ValidateUserData()
        {
            if (radioButtonOfri.Checked == false && radioButtonRefael.Checked == false && radioButtonSplit.Checked == false)
            {
                throw new ArgumentNullException("radioButtons", "Please select a user");
            }
        }

        private string ValidateDescriptionData()
        {
            if (!String.IsNullOrEmpty(textBoxDescription.Text))
            {
                return textBoxDescription.Text;
            }
            else
            {
                throw new ArgumentNullException("textBoxDescription", "Please enter expense description");
            }
        }

        private string GetOriginalCurrency()
        {
            switch (comboBoxCurrency.SelectedItem.ToString())
            {
                case "₪":
                    return "ils";
                case "$":
                    return "usd";
                case "€":
                    return "eur";
                default:
                    return "ils";
            }
        }

        double GetAmountWithExchRate(double i_amount,string i_Date, string i_fromCurr, string i_toCurr)
        {
            if (i_fromCurr == "ils")
            {
                return i_amount;
            }
            else
            {
                double exchRate;
                try
                {
                    string date = DateTime.Parse(i_Date).ToString("yyyy-MM-dd");
                    string url = String.Format("http://currencies.apps.grandtrunk.net/getrate/{0}/{1}/{2}", date, i_fromCurr, i_toCurr);
                    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                    StreamReader resStream = new StreamReader(response.GetResponseStream());
                    Double.TryParse(resStream.ReadToEnd(), out exchRate);
                }
                catch (Exception)
                {
                    exchRate = 1;
                }
                return Math.Round(i_amount * exchRate,2);
            }
        }

        private void BuildSplitExpenseRow(ref List<DataRow> i_newExpenseRow)
        {
            i_newExpenseRow.Add(m_ExpenseDataTable.NewRow());
            i_newExpenseRow[0][Fields.User] = Users.Ofri;
            i_newExpenseRow[1][Fields.User] = Users.Refael;
            i_newExpenseRow[0][Fields.Amount] = GetAmountWithExchRate(double.Parse(textBoxAmount.Text) / 2, i_newExpenseRow[0][Fields.Date].ToString(), GetOriginalCurrency(), "ils");
            i_newExpenseRow[1].ItemArray = i_newExpenseRow[0].ItemArray.Clone() as object[];
        }

        private void radioButtonSplit_CheckedChanged(object sender, EventArgs e)
        {
            if (radioButtonSplit.Checked)
            {
                checkBoxShared.Enabled = false;
            }
            else
            {
                checkBoxShared.Enabled = true;
            }
        }

        private void textBoxDescription_TextChanged(object sender, EventArgs e)
        {
            if (textBoxDescription.Text.Length == 1)
            {
                if((int)textBoxDescription.Text[0] >= (int)('A') && (int)textBoxDescription.Text[0] <= (int)('z'))
                {
                    textBoxDescription.RightToLeft = System.Windows.Forms.RightToLeft.No;    
                }
                else
                {
                    textBoxDescription.RightToLeft = System.Windows.Forms.RightToLeft.Yes;    
                }
            }
        }

        private void textBoxDescription_Leave(object sender, EventArgs e)
        {
            updateCategoryIndex();
        }

        private void updateCategoryIndex()
        {
            EnumerableRowCollection<System.Data.DataRow> result = from row in m_ExpenseDataTable.AsEnumerable()
                         .OrderByDescending(row => row.Field<DateTime>(Fields.NumDate))
                         where row.Field<string>(Fields.NumDescription) == textBoxDescription.Text
                         select row;
            if(result.Count() != 0)
            {
                comboBoxCategory.SelectedIndex = comboBoxCategory.Items.IndexOf(result.First()[Fields.NumCategory].ToString());
            }
        }
    }
   
}